"""
自定义异常类和异常处理模块
"""
from typing import Optional, Any, Dict
from fastapi import HTTPException, Request, status
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
from starlette.exceptions import HTTPException as StarletteHTTPException
import traceback
import logging

from .logging_config import get_logger

logger = get_logger("petition_exceptions")


class PetitionSystemException(Exception):
    """信访系统基础异常类"""
    
    def __init__(
        self, 
        message: str, 
        error_code: str = "SYSTEM_ERROR",
        status_code: int = 500,
        details: Optional[Dict[str, Any]] = None
    ):
        self.message = message
        self.error_code = error_code
        self.status_code = status_code
        self.details = details or {}
        super().__init__(self.message)


class AuthenticationError(PetitionSystemException):
    """认证异常"""
    
    def __init__(self, message: str = "认证失败", details: Optional[Dict[str, Any]] = None):
        super().__init__(
            message=message,
            error_code="AUTH_ERROR",
            status_code=status.HTTP_401_UNAUTHORIZED,
            details=details
        )


class AuthorizationError(PetitionSystemException):
    """授权异常"""
    
    def __init__(self, message: str = "权限不足", details: Optional[Dict[str, Any]] = None):
        super().__init__(
            message=message,
            error_code="AUTHORIZATION_ERROR",
            status_code=status.HTTP_403_FORBIDDEN,
            details=details
        )


class ValidationError(PetitionSystemException):
    """数据验证异常"""
    
    def __init__(self, message: str = "数据验证失败", details: Optional[Dict[str, Any]] = None):
        super().__init__(
            message=message,
            error_code="VALIDATION_ERROR",
            status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
            details=details
        )

class GeoAnalysisError(PetitionSystemException):
    """数据库异常"""
    
    def __init__(self, message: str = "数据库操作失败", details: Optional[Dict[str, Any]] = None):
        super().__init__(
            message=message,
            error_code="GEO_ANALYSIS_ERROR",
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            details=details
        )

class DatabaseError(PetitionSystemException):
    """数据库异常"""
    
    def __init__(self, message: str = "数据库操作失败", details: Optional[Dict[str, Any]] = None):
        super().__init__(
            message=message,
            error_code="DATABASE_ERROR",
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            details=details
        )


class DataNotFoundError(PetitionSystemException):
    """数据不存在异常"""
    
    def __init__(self, message: str = "数据不存在", details: Optional[Dict[str, Any]] = None):
        super().__init__(
            message=message,
            error_code="DATA_NOT_FOUND",
            status_code=status.HTTP_404_NOT_FOUND,
            details=details
        )


class DataAlreadyExistsError(PetitionSystemException):
    """数据已存在异常"""
    
    def __init__(self, message: str = "数据已存在", details: Optional[Dict[str, Any]] = None):
        super().__init__(
            message=message,
            error_code="DATA_ALREADY_EXISTS",
            status_code=status.HTTP_409_CONFLICT,
            details=details
        )


class FileUploadError(PetitionSystemException):
    """文件上传异常"""
    
    def __init__(self, message: str = "文件上传失败", details: Optional[Dict[str, Any]] = None):
        super().__init__(
            message=message,
            error_code="FILE_UPLOAD_ERROR",
            status_code=status.HTTP_400_BAD_REQUEST,
            details=details
        )


class AIServiceError(PetitionSystemException):
    """AI服务异常"""
    
    def __init__(self, message: str = "AI服务调用失败", details: Optional[Dict[str, Any]] = None):
        super().__init__(
            message=message,
            error_code="AI_SERVICE_ERROR",
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            details=details
        )

class TaskError(PetitionSystemException):
    """数据库异常"""

    def __init__(self, message: str = "任务创建失败", details: Optional[Dict[str, Any]] = None):
        super().__init__(
            message=message,
            error_code="TASK_CREATE_ERROR",
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            details=details
        )

class TaskExecutionError(PetitionSystemException):
    """任务执行异常"""
    
    def __init__(self, message: str = "任务执行失败", details: Optional[Dict[str, Any]] = None):
        super().__init__(
            message=message,
            error_code="TASK_EXECUTION_ERROR",
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            details=details
        )


class AnalysisError(PetitionSystemException):
    """分析异常"""
    
    def __init__(self, message: str = "分析失败", details: Optional[Dict[str, Any]] = None):
        super().__init__(
            message=message,
            error_code="ANALYSIS_ERROR",
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            details=details
        )


class StatsError(PetitionSystemException):
    """统计分析异常"""
    
    def __init__(self, message: str = "统计分析失败", details: Optional[Dict[str, Any]] = None):
        super().__init__(
            message=message,
            error_code="STATS_ERROR",
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            details=details
        )


class ReportError(PetitionSystemException):
    """报告生成异常"""
    
    def __init__(self, message: str = "报告生成失败", details: Optional[Dict[str, Any]] = None):
        super().__init__(
            message=message,
            error_code="REPORT_ERROR",
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            details=details
        )


class ConfigurationError(PetitionSystemException):
    """配置异常"""
    
    def __init__(self, message: str = "配置错误", details: Optional[Dict[str, Any]] = None):
        super().__init__(
            message=message,
            error_code="CONFIGURATION_ERROR",
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            details=details
        )


class ExternalServiceError(PetitionSystemException):
    """外部服务异常"""
    
    def __init__(self, message: str = "外部服务调用失败", details: Optional[Dict[str, Any]] = None):
        super().__init__(
            message=message,
            error_code="EXTERNAL_SERVICE_ERROR",
            status_code=status.HTTP_502_BAD_GATEWAY,
            details=details
        )


def create_error_response(
    error_code: str,
    message: str,
    status_code: int,
    details: Optional[Dict[str, Any]] = None
) -> Dict[str, Any]:
    """创建错误响应格式"""
    response = {
        "success": False,
        "error": {
            "code": error_code,
            "message": message,
        }
    }
    
    if details:
        response["error"]["details"] = details
    
    return response


async def petition_system_exception_handler(request: Request, exc: PetitionSystemException):
    """信访系统异常处理器"""
    logger.error(
        f"PetitionSystemException: {exc.message}",
        extra={
            "error_code": exc.error_code,
            "status_code": exc.status_code,
            "details": exc.details,
            "path": request.url.path,
            "method": request.method
        }
    )
    
    return JSONResponse(
        status_code=exc.status_code,
        content=create_error_response(
            error_code=exc.error_code,
            message=exc.message,
            status_code=exc.status_code,
            details=exc.details
        )
    )


async def http_exception_handler(request: Request, exc: HTTPException):
    """HTTP异常处理器"""
    logger.error(
        f"HTTPException: {exc.detail}",
        extra={
            "status_code": exc.status_code,
            "path": request.url.path,
            "method": request.method
        }
    )
    
    return JSONResponse(
        status_code=exc.status_code,
        content=create_error_response(
            error_code="HTTP_ERROR",
            message=exc.detail,
            status_code=exc.status_code
        )
    )


async def validation_exception_handler(request: Request, exc: RequestValidationError):
    """请求验证异常处理器"""
    logger.error(
        f"url: {request.url.path}, ValidationException: {exc.errors()}")
        # extra={
        #     "errors": exc.errors(),
        #     "path": request.url.path,
        #     "method": request.method
        # }
    # )
    
    return JSONResponse(
        status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
        content=create_error_response(
            error_code="VALIDATION_ERROR",
            message="请求数据验证失败",
            status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
            details={"validation_errors": exc.errors()}
        )
    )


async def general_exception_handler(request: Request, exc: Exception):
    """通用异常处理器"""
    error_message = str(exc)
    error_traceback = traceback.format_exc()
    
    logger.error(
        f"Unhandled Exception: {error_message}",
        extra={
            "exception_type": type(exc).__name__,
            "traceback": error_traceback,
            "path": request.url.path,
            "method": request.method
        }
    )
    
    return JSONResponse(
        status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
        content=create_error_response(
            error_code="INTERNAL_ERROR",
            message=f"服务器内部错误: {error_message}",
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            details={"exception_type": type(exc).__name__, "original_message": error_message}
        )
    )


def setup_exception_handlers(app):
    """设置异常处理器"""
    app.add_exception_handler(PetitionSystemException, petition_system_exception_handler)
    app.add_exception_handler(HTTPException, http_exception_handler)
    app.add_exception_handler(RequestValidationError, validation_exception_handler)
    app.add_exception_handler(StarletteHTTPException, http_exception_handler)
    app.add_exception_handler(Exception, general_exception_handler)


# 异常处理装饰器
def handle_exceptions(func):
    """异常处理装饰器"""
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except PetitionSystemException:
            # 已知异常，直接抛出
            raise
        except Exception as e:
            # 未知异常，包装为系统异常
            logger.error(f"Unhandled exception in {func.__name__}: {str(e)}")
            raise PetitionSystemException(
                message=f"操作失败: {str(e)}",
                error_code="INTERNAL_ERROR",
                details={"function": func.__name__, "exception_type": type(e).__name__}
            )
    
    return wrapper


# 数据库操作异常处理
def handle_db_errors(func):
    """数据库操作异常处理装饰器"""
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception as e:
            logger.error(f"Database error in {func.__name__}: {str(e)}")
            raise DatabaseError(
                message=f"数据库操作失败: {str(e)}",
                details={"function": func.__name__, "exception_type": type(e).__name__}
            )
    
    return wrapper


# AI服务异常处理
def handle_ai_service_errors(func):
    """AI服务异常处理装饰器"""
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception as e:
            logger.error(f"AI service error in {func.__name__}: {str(e)}")
            raise AIServiceError(
                message=f"AI服务调用失败: {str(e)}",
                details={"function": func.__name__, "exception_type": type(e).__name__}
            )
    
    return wrapper

